#include "mklm_server_manager.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDateTime>
#include <QHostAddress>
#include <QAbstractSocket>

namespace infrastructure {
	namespace vehicle {
		namespace mklm {

			// 静态成员初始化
			MklmServerManager* MklmServerManager::s_instance = nullptr;

			MklmServerManager* MklmServerManager::instance()
			{
				if (!s_instance) {
					s_instance = new MklmServerManager();
				}
				return s_instance;
			}

			MklmServerManager::MklmServerManager(QObject* parent)
				: QObject(parent)
			{
			}

			MklmServerManager::~MklmServerManager()
			{
				shutdown();
			}

			bool MklmServerManager::initialize(quint16 listenPort, std::shared_ptr<kernel::ILogger> logger)
			{
				if (m_isRunning) {
					if (logger) {
						logger->warning("MKLM Server 已在运行中");
					}
					return true;
				}

				m_listenPort = listenPort;
				m_logger = logger;

				// 创建 TCP Server
				m_server = std::make_unique<io::TcpSocketServer>(10, this);

				// 连接信号
				connect(m_server.get(), &io::TcpSocketServer::sig_connectClient,
					this, &MklmServerManager::onClientConnected);
				connect(m_server.get(), &io::TcpSocketServer::sig_sockDisConnect,
					this, &MklmServerManager::onClientDisconnected);

				// 开始监听
				if (!m_server->listen(QHostAddress::Any, listenPort)) {
					if (m_logger) {
						m_logger->error(QString("MKLM Server 无法监听端口 %1: %2")
							.arg(listenPort)
							.arg(m_server->errorString()));
					}
					return false;
				}

				m_isRunning = true;

				if (m_logger) {
					m_logger->info(QString("MKLM Server 已启动，监听端口 %1").arg(listenPort));
				}

				return true;
			}

			void MklmServerManager::registerAgvCallback(int agvNumber, StatusUpdateCallback callback)
			{
				m_agvCallbacks[agvNumber] = callback;
				m_knownMklmAgvs.insert(agvNumber);

				if (m_logger) {
					m_logger->info(QString("注册 AGV %1 到 MKLM Server").arg(agvNumber));
				}
			}

			void MklmServerManager::unregisterAgvCallback(int agvNumber)
			{
				m_agvCallbacks.erase(agvNumber);

				if (m_logger) {
					m_logger->info(QString("注销 AGV %1 从 MKLM Server").arg(agvNumber));
				}
			}

			void MklmServerManager::shutdown()
			{
				if (!m_isRunning) {
					return;
				}

				if (m_logger) {
					m_logger->info("停止 MKLM Server");
				}

				// 清理所有协议解析器
				for (auto& pair : m_protocols) {
					delete pair.second;
				}
				m_protocols.clear();

				if (m_server) {
					m_server->close();
					m_server.reset();
				}

				m_agvCallbacks.clear();
				m_isRunning = false;
			}

			void MklmServerManager::onClientConnected(qint64 socketDescriptor, const QString& ip, quint16 port)
			{
				if (m_logger) {
					m_logger->info(QString("MKLM 客户端已连接: %1:%2 (descriptor: %3)")
						.arg(ip).arg(port).arg(socketDescriptor));
				}

				// 获取客户端连接
				auto clients = m_server->getClients();
				auto it = clients.find(socketDescriptor);
				if (it != clients.end()) {
					io::TcpSocketClient* client = it.value();

					// 创建协议解析器
					robokit::RProtocol* protocol = new robokit::RProtocol(client, this);

					// 设置协议回调（捕获socketDescriptor以便后续关联AGV）
					protocol->SetNnalyzeCallBackFunc(
						[this, socketDescriptor](uint16_t cmdType, QByteArray& data) {
						this->onProtocolDataReceived(cmdType, data, socketDescriptor);
					}
					);

					// 保存协议解析器
					m_protocols[socketDescriptor] = protocol;

					if (m_logger) {
						m_logger->info(QString("MKLM 协议解析器已创建 (descriptor: %1)").arg(socketDescriptor));
					}
				}
			}

			void MklmServerManager::onClientDisconnected(qint64 socketDescriptor, const QString& ip, quint16 port)
			{
				if (m_logger) {
					m_logger->warning(QString("MKLM 客户端断开连接: %1:%2 (descriptor: %3)")
						.arg(ip).arg(port).arg(socketDescriptor));
				}

				// 删除协议解析器
				auto it = m_protocols.find(socketDescriptor);
				if (it != m_protocols.end()) {
					delete it->second;
					m_protocols.erase(it);
				}
			}

			void MklmServerManager::onProtocolDataReceived(uint16_t cmdType, QByteArray& data, qint64 socketDescriptor)
			{
				// 只处理状态上传命令
				if (cmdType != CMD_STATUS_UPLOAD) {
					return;
				}

				QJsonParseError jsonError;
				QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError);

				if (jsonError.error != QJsonParseError::NoError) {
					if (m_logger) {
						m_logger->warning(QString("MKLM JSON 解析失败: %1")
							.arg(jsonError.errorString()));
					}
					return;
				}

				QJsonObject rootObject = doc.object();

				// 解析并分发
				parseAndDispatchStatus(rootObject, socketDescriptor);
			}

			void MklmServerManager::parseAndDispatchStatus(const QJsonObject& jsonObj, qint64 socketDescriptor)
			{
				// 提取 AGV 编号
				int agvNumber = jsonObj.value("agv_num").toInt();

				if (agvNumber == 0) {
					if (m_logger) {
						m_logger->warning("收到的状态数据缺少 agv_num 字段或为 0");
					}
					return;
				}

				// 记录 AGV编号 -> socket descriptor 映射（用于后续获取IP地址）
				m_agvSocketMap[agvNumber] = socketDescriptor;

				// 构建 MKLM 状态 DTO
				kernel::dtos::MklmAgvStatusDTO status;

				// 基本信息
				status.agvNumber = agvNumber;

				// 优先从被动连接中提取 IP，如果协议中提供字段则作为兜底
				QString agvIp = getAgvIpAddress(agvNumber);
				if (agvIp.isEmpty()) {
					agvIp = jsonObj.value("ip").toString();
				}
				status.ip = agvIp;

				// 位置信息
				status.x = jsonObj.value("x").toDouble();
				status.y = jsonObj.value("y").toDouble();
				status.angle = jsonObj.value("angle").toDouble();
				status.confidence = jsonObj.value("confidence").toDouble();

				// 站点信息
				status.currentStation = jsonObj.value("current_station").toString();
				status.lastStation = jsonObj.value("last_station").toString();
				status.targetId = jsonObj.value("target_id").toString();
				status.currentMap = jsonObj.value("current_map").toString();

				// 区域信息
				QJsonArray areaIds = jsonObj.value("area_ids").toArray();
				for (const auto& areaId : areaIds) {
					status.areaIds.append(areaId.toString());
				}

				// 状态信息
				status.power = jsonObj.value("power").toInt();
				status.chargeState = jsonObj.value("charge_state").toBool();
				status.locked = jsonObj.value("locked").toBool();
				status.blocked = jsonObj.value("blocked").toBool();
                status.driverEmc = jsonObj.value("driver_emc").toBool();
				status.mode = jsonObj.value("mode").toInt();
				status.rollerMode = jsonObj.value("roller_mode").toBool();
				status.liftStage = jsonObj.value("lift_stage").toInt();

				// 任务信息
				status.taskStatus = jsonObj.value("task_status").toInt();
				status.taskType = jsonObj.value("task_type").toInt();
				status.taskListCount = jsonObj.value("task_list_cnt").toInt();

				// 路径信息
				QJsonArray finishedPath = jsonObj.value("finished_path").toArray();
				for (const auto& station : finishedPath) {
					status.finishedPath.append(station.toString());
				}

				QJsonArray unfinishedPath = jsonObj.value("unfinished_path").toArray();
				for (const auto& station : unfinishedPath) {
					status.unfinishedPath.append(station.toString());
				}

				// API信息
				status.retCode = jsonObj.value("ret_code").toInt();
				status.createOn = jsonObj.value("create_on").toString();
				status.errMsg = jsonObj.value("err_msg").toString();

				// 时间戳
				status.uploadTime = QDateTime::currentDateTime();

				// 检测是否为未知AGV
				if (m_knownMklmAgvs.find(agvNumber) == m_knownMklmAgvs.end()) {
					// 发现新的MKLM AGV，发射信号
					if (m_logger) {
						m_logger->info(QString("检测到未注册的 MKLM AGV: %1").arg(agvNumber));
					}
					emit unknownMklmAgvDetected(agvNumber, status);
					return;
				}

				// 查找对应的回调
				auto it = m_agvCallbacks.find(agvNumber);
				if (it == m_agvCallbacks.end()) {
					if (m_logger) {
						m_logger->debug(QString("收到未注册回调的 AGV %1 的状态数据").arg(agvNumber));
					}
					return;
				}

				// 调用回调
				it->second(status);
			}

			QString MklmServerManager::getAgvIpAddress(int agvNumber) const
			{
				// 查找AGV对应的socket descriptor
				auto socketIt = m_agvSocketMap.find(agvNumber);
				if (socketIt == m_agvSocketMap.end()) {
					if (m_logger) {
						m_logger->warning(QString("未找到 AGV %1 的连接信息").arg(agvNumber));
					}
					return QString();
				}

				qint64 socketDescriptor = socketIt->second;

				// 查找对应的协议解析器
				auto protocolIt = m_protocols.find(socketDescriptor);
				if (protocolIt == m_protocols.end()) {
					if (m_logger) {
						m_logger->warning(QString("未找到 descriptor %1 的协议解析器").arg(socketDescriptor));
					}
					return QString();
				}

				// 从协议的TCP连接获取对端地址
				robokit::RProtocol* protocol = protocolIt->second;
				if (protocol && protocol->m_tcpConnection) {
					QHostAddress peerAddr = protocol->m_tcpConnection->peerAddress();
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
					if (peerAddr.protocol() == QAbstractSocket::IPv6Protocol) {
						Q_IPV6ADDR rawAddr = peerAddr.toIPv6Address();
						bool isMapped = true;
						for (int i = 0; i < 5; ++i) {
							if (rawAddr[i] != 0) {
								isMapped = false;
								break;
							}
						}
						if (isMapped && rawAddr[5] == 0xffff) {
							quint32 ipv4 =
							    (quint32(rawAddr[6]) << 16) | quint32(rawAddr[7]);
							peerAddr = QHostAddress(ipv4);
						}
					}
#endif
					return peerAddr.toString();
				}

				return QString();
			}

		} // namespace mklm
	} // namespace vehicle
} // namespace infrastructure
